from django.db.models import F
from django.http import JsonResponse
from rest_framework.response import Response
from News import models
from rest_framework.views import APIView
from News.serializers import TypeSerializer,NewsSerializer,NewsDtailSerializer,NewsHotSerializer
from Blog.util import LimitPagination,DataFailed
from Blog.blog import getUser
import json
from django.db import transaction
#获取类型
class Type(APIView):
    authentication_classes = []
    def get(self, request, *args, **kwargs):
        #查询News_Type表，返回了QuerySet对象
        try:
            res = models.Type.objects.filter(status=1).all().values('id','name')
        except:
            raise DataFailed({'status': '201', 'msg': '查询失败'})
        #调用序列化方法，把对象转化为字符串 序列化就是把对象转换成字符串，反序列化就是把字符串转换成对象
        serializer = TypeSerializer(res, many=True)
        result = {'status': '200', 'msg': '获取成功','data':serializer.data}
        #Response返回字符串对象，返回对象报错
        return Response(result)

#新闻列表
class NewsList(APIView):
    authentication_classes = []
    def get(self, request, *args, **kwargs):
        id = request.GET.get('id', None)
        type_id = request.GET.get('type', None)
        if id is None:
            # 查询News_news表，返回了QuerySet对象
            if type_id is None:
                res = models.News.objects.filter(status=1).values('id', 'type', 'cover', 'user', 'title', 'content','source',
                                                                  'is_recommend', 'ctime', 'view', 'comments', 'goods'
                                                                  ).order_by('ctime')
            else:
                type = getType(type_id)
                res = models.News.objects.filter(status=1, type=type).values('id', 'type', 'cover', 'user', 'title',
                                                                             'content','source', 'is_recommend', 'ctime', 'view',
                                                                             'comments', 'goods'
                                                                            ).order_by('ctime')
        # Response返回字符串对象，返回对象报错
        else:
            try:
                news = models.News.objects.get(id=id)
            except:
                raise DataFailed({"status": "202", "msg": "新闻不存在"})
            news.view = F('view') + 1
            news.save()
            res = models.News.objects.filter(status=1, id=id).values('id', 'type', 'cover', 'user', 'title', 'content','source',
                                                                     'is_recommend',
                                                                     'ctime', 'view', 'comments', 'goods'
                                                                     ).order_by('ctime')
        if id is None:
            p = LimitPagination()  # 注册分页
            page_user_list = p.paginate_queryset(queryset=res, request=request, view=self)
            ser = NewsSerializer(page_user_list, many=True)  # 可允许多个
            return p.get_paginated_response("200", "获取成功", ser.data)
        else:
            ser = NewsDtailSerializer(res, many=True)
            response = {'status': '200', 'msg': "查找成功", 'data': ser.data}
            return Response(response)

#点赞操作
class Goods(APIView):
    def get(self, request, *args, **kwargs):
        response = {'status': "200", 'msg': '点赞成功'}
        user_id = request.user[0]['id']
        user = getUser(user_id)
        news_id = request.GET.get('news', None)
        if news_id is None:
            raise DataFailed({"status": "202", "msg": "新闻不存在"})
        news = getNews(news_id)
        is_goods = models.NGood.objects.filter(news=news,user=user).exists()
        if is_goods:
            raise DataFailed({"status": "201", "msg": "您已点赞该新闻"})
        try:
            with transaction.atomic():
                obj = models.NGood(news=news,user=user)
                obj.save()
                #点赞+1
                news.goods = F('goods') + 1
                news.save()
        except Exception as e:
            print(e)
            raise DataFailed({"status": "201", "msg": "点赞异常"})

        get_news_goods = getNews(news_id)
        goods = get_news_goods.goods
        response['goods'] = goods

        return JsonResponse(response, safe=False)

#评论操作
class Commtent(APIView):
    def post(self, request, *args, **kwargs):
        # print(request.body)
        try:
            data = json.loads(request.body)
        except:
            raise DataFailed({"status": "203", "msg": "数据结构错误"})
        try:
            news_id = data['id']
        except:
            raise DataFailed({"status": "201", "msg": "新闻不存在"})
        try:
            post_id = data['post_id']
        except:
            post_id = None
        content = data['content']
        if content is "":
            raise DataFailed({"status": "201", "msg": "内容不为空"})
        user_id = request.user[0]['id']
        if news_id is None:
            raise DataFailed({"status": "201", "msg": "新闻不存在"})
        else:
            user = getUser(user_id)
            news = getNews(news_id)
            response = {'status': "200", 'msg': "发布成功"}
            if post_id is None:
                post = None
                topic = 0
            else:
                post = getPost(post_id)
                topic = post.topic+ 1
            try:
                with transaction.atomic():
                    obj = models.NComment(news=news, user=user, post=post, content=content,topic=topic)
                    obj.save()
                    # 评论+1
                    news.comments = F('comments') + 1
                    news.save()
            except Exception as e:
                raise DataFailed({"status": "201", "msg": "发布异常"})
            return JsonResponse(response, safe=False)

#热门博客
class HotNews(APIView):
    authentication_classes = []
    def get(self, request, *args, **kwargs):
        res = models.News.objects.filter(status=1).values('id', 'title', 'ctime').order_by('view','-ctime')[:5]
        ser = NewsHotSerializer(res, many=True)
        response = {'status': "200", 'msg': "查找成功", 'data': ser.data}
        return Response(response)

#判断点赞收藏
class is_operation(APIView):
    def get(self, request, *args, **kwargs):
        news_id = request.GET.get('news', None)
        user_id = request.user[0]['id']
        user = getUser(user_id)
        news = getNews(news_id)
        response = {'status': "200", 'msg': '查询成功'}
        data = {}
        is_goods = models.NGood.objects.filter(news=news, user=user).exists()
        if is_goods:
           data['good'] = 1
        else:
            data['good'] = 0
        response['data'] = data
        return Response(response)

#类型
def getType(id):
    try:
        res = models.Type.objects.get(id=id)
    except:
        raise DataFailed({"status": "202", "msg": "类型不存在"})
    return res
#新闻
def getNews(id):
    try:
        ret = models.News.objects.get(id=id)
    except:
        raise DataFailed({"status": "202", "msg": "新闻不存在"})
    return ret

#获得回复
def getPost(id):
    try:
        ret = models.NComment.objects.get(id=id)
    except:
        raise DataFailed({"status": "202", "msg": "回复不存在"})
    return ret
